package net.jescort.domain.user;

import java.util.Calendar;
import java.util.HashSet;
import java.util.Set;
import net.gelif.kernel.core.domain.AbstractPersistable;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.shiro.authz.Permission;
import com.google.common.collect.Sets;

//@Configurable(value = "user", autowire = Autowire.BY_TYPE)
public class User extends AbstractPersistable<Integer>
{
    private static final long serialVersionUID = 6875770738871326945L;
    
    public User()
    {
    }
    
    public User(Integer id)
    {
        this.id = id;
    }
    
    private Integer id;
    private String username;
    private String password;
    private Name name;
    private String nickname;
    private String timezone;
    private Calendar createdate;
    private Set<Email> emails;
    private Set<Address> addresses;
    private Set<Group> groups;
    private Set<org.apache.shiro.authz.Permission> permissions = Sets.newHashSetWithExpectedSize(20);
    
    public Integer getId()
    {
        return id;
    }
    
    public void setId(Integer id)
    {
        this.id = id;
    }
    
    public String getUsername()
    {
        return username;
    }
    
    public void setUsername(String username)
    {
        this.username = username;
    }
    
    public String getPassword()
    {
        return password;
    }
    
    public void setPassword(String password)
    {
        this.password = password;
    }
    
    public Name getName()
    {
        return name;
    }
    
    public void setName(Name name)
    {
        this.name = name;
    }
    
    public String getNickname()
    {
        return StringUtils.isNotBlank(nickname) ? nickname : username;
    }
    
    public void setNickname(String nickname)
    {
        this.nickname = nickname;
    }
    
    public String getTimezone()
    {
        return timezone;
    }
    
    public void setTimezone(String timezone)
    {
        this.timezone = timezone;
    }
    
    public Calendar getCreatedate()
    {
        return createdate;
    }
    
    public void setCreatedate(Calendar createdate)
    {
        this.createdate = createdate;
    }
    
    public Set<Email> getEmails()
    {
        return emails;
    }
    
    public void setEmails(Set<Email> emails)
    {
        this.emails = emails;
    }
    
    public Set<Address> getAddresses()
    {
        return addresses;
    }
    
    public void setAddresses(Set<Address> addresses)
    {
        this.addresses = addresses;
    }
    
    public Set<Group> getGroups()
    {
        return groups;
    }
    
    public void setGroups(Set<Group> groups)
    {
        this.groups = groups;
    }
    
    public Set<Role> getRoles()
    {
        Set<Role> roles = new HashSet<Role>();
        for(Group group : getGroups())
        {
            roles.addAll(group.getRoles());
        }
        return roles;
    }
    
    public Set<Permission> getPermissions()
    {
        return permissions;
    }
    
    public void setPermissions(Set<Permission> permissions)
    {
        this.permissions = permissions;
    }
    
    @Override
    public boolean equals(Object object)
    {
        if(this == object)
        {
            return true;
        }
        if(!(object instanceof User))
        {
            return false;
        }
        final User user = (User)object;
        return new EqualsBuilder().append(username, user.getUsername()).isEquals();
    }
    
    @Override
    public int hashCode()
    {
        return new HashCodeBuilder().append(id).toHashCode();
    }
    
    @Override
    public String toString()
    {
        ToStringBuilder sb = new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).append("id", this.id).append("name", null != this.name ? this.name.toString() : null).append("username", this.username).append("password", this.password).append("nickname", this.nickname).append("timezone", this.timezone).append("createdate", null != this.createdate ? String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", this.createdate) : null);
        Set<Group> groups = getGroups();
        if(groups != null)
        {
            sb.append("groups: ");
            for(Group group : groups)
            {
                sb.append(group.getName());
                sb.append(", ");
            }
        }
        else
        {
            sb.append("No Groups");
        }
        return sb.toString();
    }
}
